﻿using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using LuaInterface;
using System.IO;
using UnityEngine.Networking;
using System.Text;
using ThinkingAnalytics;

namespace YanhuaMMO {
    public class GameManager : Manager {
        protected static bool Initialize = false;
        private bool _hasUpdateAllResource = false;
        private readonly List<string> _downloadFiles = new List<string>();
        private readonly List<string[]> _updateMapFiles = new List<string[]>();
        private float _updateItemMB = 0f;
		private bool hasDownloadFileError = false;
		private bool hasDownloadFileNetworkError = false;
        GUIStyle fontStyle = null;
        GUIStyle fontStyle2 = null;

		float pauseTime = 0;
        bool needSilenceUpdate = false;
        /// <summary>
        /// 初始化游戏管理器
        /// </summary>
        void Awake() {
            //QualitySettings.vSyncCount = 2;
            //Init();

#if UNITY_EDITOR
            fontStyle = new GUIStyle();
            fontStyle.normal.background = null;
            fontStyle.normal.textColor = Color.green;
            fontStyle.fontSize = 28;

            fontStyle2 = new GUIStyle();
            fontStyle2.normal.background = null;
            fontStyle2.normal.textColor = Color.black;
            fontStyle2.fontSize = 28;
#endif
        }

        private void Start()
        {
            QualitySettings.vSyncCount = 2;
            Init();
        }

#if UNITY_EDITOR
        void OnGUI()
        {
            GUI.Label(new Rect(3, Screen.height - 27, 100, 200), "服务器id=" + AppConst.ServerId, fontStyle2);
            GUI.Label(new Rect(0, Screen.height - 30, 100, 200), "服务器id=" + AppConst.ServerId, fontStyle);
        }
#endif
        /// <summary>
        /// 初始化
        /// </summary>
        void Init() {
            DontDestroyOnLoad(gameObject);  //防止销毁自己

            if (Application.isEditor)
            {
                AppConst.DebugMode = true;
#if CLIENT_BUNDLE
                AppConst.BundleMode = true;
                AppConst.UpdateMode = true;
#else
                AppConst.BundleMode = false;
                AppConst.UpdateMode = false;
#endif
                AppConst.LuaBundleMode = true;                    
            }
            else if (Application.isMobilePlatform)
            {
#if SDK_BILIBILI || SDK_XN
                AppConst.DebugMode = false;
#else
                 AppConst.DebugMode = true;
#endif
                AppConst.BundleMode = true;
                AppConst.UpdateMode = true;
                AppConst.LuaBundleMode = true;                    
            }
            else
            {
                AppConst.DebugMode = true;
                AppConst.BundleMode = false;
                AppConst.UpdateMode = false;
                AppConst.LuaBundleMode = false;
            }

            CheckExtractResource(); //释放资源
            Screen.sleepTimeout = SleepTimeout.NeverSleep;
            Application.targetFrameRate = AppConst.GameFrameRate;
            Application.runInBackground = true;
        }

        public void DisableUpdate()
        {
            AppConst.DebugMode = false;
        }

        private void OnApplicationQuit()
        {
           var wm = AppFacade.Instance.GetManager<WebMsgManager>(ManagerName.WebMsg);
            if (wm)
                wm.DisConnect();

            Util.CallMethod("Game", "OnApplicationQuit");
        }
        public void CheckSilenceUpdate()
        {
            if(Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
            {
                if (needSilenceUpdate)
                {
                    Debug.Log("直接进入静默热更流程");
                    StartCoroutine(OnUpdateResource());
                }
                else 
                {
                    Debug.Log("静默热更监测");
                    StartCoroutine(OnCheckSilence());
                }
            }
           
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void CheckExtractResource() {
            var isExists = Directory.Exists(Util.DataPath) && File.Exists(Util.DataPath + "original.txt");
            //Debug.Log(">>>>>>isExists" + Util.DataPath);
            if (isExists)
            {
                bool newAPK = false;
                string[] version = File.ReadAllLines(Util.DataPath + "original.txt");
                Debug.Log("Version:" + AppConst.originVersion);
                if (version[0].Length > 0)
                {
                    Debug.Log("local Version:" + version[0]);
                    string[] originVersions = AppConst.originVersion.Split('.');
                    string[] versions = version[0].Split('.');

                    if (int.Parse(originVersions[0]) > int.Parse(versions[0]) || int.Parse(originVersions[1]) > int.Parse(versions[1]) || int.Parse(originVersions[2]) > int.Parse(versions[2]))
                    {
                        newAPK = true;
                    }
                }
                if (!newAPK)
                {
                    StartCoroutine(OnUpdateResource());
                    return;   //文件已经解压过了，自己可添加检查文件列表逻辑
                }
            }

            StartCoroutine(OnExtractResource());    //启动释放协成 
        }

        IEnumerator OnExtractResource() {
			// AppView.ShowUpdate(); 
			yield return CheckDrawingState();
            CheckAudit();
            var dataPath = Util.DataPath;  //数据目录
            var resPath = Util.AppContentPath(); //游戏包资源目录
            //Debug.Log(">>>>>>>resPath==" + resPath);
            var message = "资源解压中";
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);

            if (Directory.Exists(dataPath))
            {
                // WG 不需要全部删除 为其他功能留后路：eg：调试Lua加载
                // Directory.Delete(dataPath, true); 
                /*
                string[] deleteFiles = { "files.txt", "log.txt", "version.txt" };
                foreach (var t in deleteFiles)
                {
                    var path = dataPath + t;
                    if (File.Exists(path))
                    {
                        File.Delete(path);
                    }
                }
               */

                Directory.Delete(dataPath, true);
            }
            //else 
            {
                Directory.CreateDirectory(dataPath);

                File.WriteAllText(dataPath + "original.txt", AppConst.originVersion);
            }

            //安装包版本号
            var inversion = resPath + "version.txt";
            var outVersion = dataPath + "version.txt";
            if (File.Exists(outVersion)) 
                File.Delete(outVersion);
            //Debug.LogError(">>>>>>>outVersion======");
            if (Application.platform == RuntimePlatform.Android 
                                                                || Application.platform == RuntimePlatform.OSXEditor
                                                                || Application.platform == RuntimePlatform.WindowsEditor)//|| Application.platform == RuntimePlatform.IPhonePlayer，iOS的文件用copy，download file无效 
            {
                //Debug.LogError(">>>>>>>DownLoadFile" + outVersion);
                yield return DownLoadFile(inversion, outVersion);
                //Debug.LogError(">>>>>>>DownLoadFile inversion==" + inversion);
            }
            else
            {
#if UNITY_EDITOR && !CLIENT_BUNDLE

#else
            if(File.Exists(inversion))
                File.Copy(inversion, outVersion, true);   
#endif
            }
            yield return new WaitForEndOfFrame();
            var bUpdate = false;
#if UNITY_EDITOR && !CLIENT_BUNDLE
            var versions=new string[]{"21213213"};
#else

            if (!File.Exists(outVersion))
            {
                OnResourceInited();
                yield break;
            }

            string[] versions = File.ReadAllLines(outVersion);
            if (versions[0].Length > 0)
            {
                AppConst.appVersion = versions[0];
            }
            else
            {
                Util.LogError(">>>>>>>>安装包版本文件错误！！！");
                yield break;
            }



            //安装包文件列表
            string infile = resPath + "files.txt";
            string outfile = dataPath + "files.txt";
            if (File.Exists(outfile))
                File.Delete(outfile);

            if (Application.platform == RuntimePlatform.Android )//|| Application.platform == RuntimePlatform.IPhonePlayer，iOS的文件用copy，download file无效 
            {
                yield return DownLoadFile(infile, outfile);
            }
            else{
                 if(File.Exists(infile))
                    File.Copy(infile, outfile, true);
            }
            yield return new WaitForEndOfFrame();
            //解析版本号
            long appVersion = long.Parse(AppConst.appVersion.Replace(".",""));

            if (!AppConst.UpdateMode)
            {
                OnResourceInited();
                yield break;
            }

            //资源服务器版本号
            string Assets_Url = AppConst.WebUrl;    //资源服务器地址
            string random = DateTime.Now.ToString("yyyymmddhhmmss");
            string inremote = Assets_Url + "version.txt?v=" + random;
            string outremote = dataPath + "remote_version.txt";
            if (File.Exists(outremote))
                File.Delete(outremote);
            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer 
                                                                || Application.platform == RuntimePlatform.OSXEditor
                                                                || Application.platform == RuntimePlatform.WindowsEditor)
            {
                yield return DownLoadFile(inremote, outremote);
            }
            else{
                if(File.Exists(inremote))
                    File.Copy(inremote, outremote, true);
            }
            yield return new WaitForEndOfFrame();
            //比较版本号
            if (!File.Exists(outremote))
            {
                OnResourceInited();
                yield break;
            }
            string[] remotes = File.ReadAllLines(outremote);
            long remoteint = long.Parse(remotes[0].Replace(".",""));
            bUpdate = remoteint > appVersion;
            //最小强更版本控制
            if (remotes.Length > 2)
            {
                var minVersion = remotes[2];
                var minVerLong = long.Parse(minVersion.Replace(".", ""));
                if(appVersion < minVerLong)
                {
                    bUpdate = true;
                }
            }
#endif
            message = "解压完成，准备进入游戏";
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
            yield return new WaitForSeconds(0.1f);

            if(bUpdate)
            {
                StartCoroutine(OnUpdateResource());
            }
            else
            {
                OnResourceInited();
            }

            yield break;
        }

        /// <summary>
        /// 开始下载 这里看是否需要下载
        /// </summary>
        /// <returns></returns>
        IEnumerator OnUpdateResourceStart() 
        {
            Dictionary<string, object> _dic = new Dictionary<string, object>();
            if (!AppConst.UpdateMode)
            {
                _dic.Add("reason", "update_mode_closed");
                ThinkingAnalyticsAPI.Track("not_need_hot_update", _dic);
                OnResourceInited();
                yield break;
            }
            var message = string.Empty;
            var dataPath = Util.DataPath;  //数据目录
            var resPath = Util.AppContentPath(); //游戏包资源目录
            var Assets_Url = AppConst.WebUrl;    //资源服务器地址
            var random = DateTime.Now.ToString("yyyymmddhhmmss");
            string preVersion = "";
            //读取版本号
            var version_file = dataPath + "version.txt";
            if (File.Exists(version_file))
            {
                var versions = File.ReadAllLines(version_file);
                if (versions[0].Length > 0)
                {
                    AppConst.appVersion = versions[0];
                    preVersion = AppConst.appVersion;
                }
            }
            else
            {
                Util.LogError("安装包版本文件错误！！！");
                yield break;
            }
            //解析版本号
            var appVersion = long.Parse(AppConst.appVersion.Replace(".",""));

            //资源服务器版本号
            var inremote = Assets_Url + "version.txt?v=" + random;
            var outremote = dataPath + "remote_version.txt";
            if (File.Exists(outremote))
                File.Delete(outremote);

            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer 
                                                                || Application.platform == RuntimePlatform.OSXEditor
                                                                || Application.platform == RuntimePlatform.WindowsEditor)
            {
                yield return DownLoadFile(inremote, outremote);
            }
            else
            {
                if (File.Exists(inremote))
                    File.Copy(inremote, outremote, true);
            }
            yield return new WaitForEndOfFrame();
			if (hasDownloadFileNetworkError)
			{
				//facade.SendMessageCommand(NotiConst.DOWNLOAD_FILE_FAILED);
				yield break;
			}
			//比较版本号
			if (!File.Exists(outremote)) 
            {
                _dic.Add("reason", "local_version_exist");
                ThinkingAnalyticsAPI.Track("not_need_hot_update", _dic);
                OnResourceInited();
                yield break;
            }
            var remotes = File.ReadAllLines(outremote);
            var remote = remotes[0];
            AppConst.appVersion = remote;
            //最小强更版本控制
            if (remotes.Length > 2)
            {
                var minVersion = remotes[2];
                var minVerLong = long.Parse(minVersion.Replace(".", ""));
                if(appVersion < minVerLong)
                {
                    //进入强制更新流程
                    List<string> changeMsg = new List<string>();
                    if (remotes.Length > 4)
                    {
                        changeMsg.Add(remotes[2]);//最低版本号
                        Debug.Log("remotes[2]===" + remotes[2]);
                        Debug.Log("remotes[3]===" + remotes[3]);
                        Debug.Log("remotes[4]===" + remotes[4]);
                        changeMsg.Add(remotes[3]);//下载包地址
                        changeMsg.Add(remotes[4]);//下载包大小
                    }
                    else
                    {
                        Debug.LogError("换包，version内容不够");
                    }
                    facade.SendMessageCommand(NotiConst.CHANGE_PACKAGE, changeMsg);
                    yield break;
                }
            }

            var vsTemp = long.Parse(remote.Replace(".",""));
            if (vsTemp <= appVersion) 
            {
                _dic.Add("reason", "reomote_version_less");
                ThinkingAnalyticsAPI.Track("not_need_hot_update", _dic);
                OnResourceInited();
                yield break;
            }
            //静默更新，判断
            if (remotes.Length > 1)
            {
                var silence = remotes[1];
               
                if (silence == "1")
                {
                    if (needSilenceUpdate)
                    {
                        //这是进入游戏后，静默更新流程
                    }
                    else
                    {
                        //要静默的版本，阻断，等进入游戏后再更
                        AppConst.appVersion = preVersion;//没有更新，先显示之前的版本号
                        needSilenceUpdate = true;
                        OnResourceInited();
                        yield break;
                    }
                }
            }
            //更新新版本
            message = "发现新版本：" + remote;
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
            var filesUrl = Assets_Url + remote + "\\" + "files.txt?v=" + random;
            var filesFile = dataPath + remote + "_files.txt";
            if (File.Exists(filesFile))
                File.Delete(filesFile);

            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer 
                                                                || Application.platform == RuntimePlatform.OSXEditor
                                                                || Application.platform == RuntimePlatform.WindowsEditor)
            {
                yield return DownLoadFile(filesUrl, filesFile);
            }
            else
            {
                if (File.Exists(filesUrl))
                    File.Copy(filesUrl, filesFile, true);
            }
			if (hasDownloadFileError)
			{
				//facade.SendMessageCommand(NotiConst.DOWNLOAD_FILE_FAILED);
				yield break;
			}
            yield return new WaitForEndOfFrame();
            if (File.Exists(filesFile))
            {
                Dictionary<string, string> localFileToMd5 = new Dictionary<string, string>();
                var localFilesPath = Util.DataPath + preVersion + "_files.txt";
                if (!File.Exists(localFilesPath)) localFilesPath = Util.DataPath + "files.txt";
                string[] in_files = File.ReadAllLines(localFilesPath); 
                foreach (string s in in_files) 
                {
                    var sp = s.Split('|');
                    localFileToMd5[sp[0]] = sp[1];
                }
                //上次已更新文件
                Dictionary<string, string> hasUpdateMd5 = new Dictionary<string, string>();
                var hasUpdateFilesPath = Util.DataPath + "update_files.txt";
                if (File.Exists(hasUpdateFilesPath)) 
                {
                    string[] update_files = File.ReadAllLines(hasUpdateFilesPath);
                    foreach (string s in update_files)
                    {
                        var sp = s.Split('|');
                        hasUpdateMd5[sp[0]] = sp[1];
                        _updateItemMB += float.Parse(sp[2]) / 1024;
                    }
                }

                List<string> updateFiles = new List<string>();
                string[] list_files = File.ReadAllLines(filesFile);
                for (int j = 0; j < list_files.Length; j++)
                {
                    if (list_files[j].Length <= 0)
                        continue;

                    string[] keyValue = list_files[j].Split('|');
                    if (keyValue[0].EndsWith(".meta") || keyValue[0].EndsWith(".txt") || keyValue[0].EndsWith(".bat"))
                        continue;

                    string remoteMd5 = keyValue[1];
                    string localMd5 = "";
                    string updateMd5 = "";
                    if (localFileToMd5.ContainsKey(keyValue[0])) 
                    {
                        localMd5 = localFileToMd5[keyValue[0]];
                    }
                    if (hasUpdateMd5.TryGetValue(keyValue[0], out string md5)) 
                    {
                        updateMd5 = md5;
                    }
                    if (remoteMd5 != localMd5 && remoteMd5 != updateMd5)
                    {
                        updateFiles.Add(list_files[j]);
                    }
                }
                if (updateFiles.Count > 0)
                {
                    _dic.Add("remote_version", remote);
                    ThinkingAnalyticsAPI.Track("start_hot_update", _dic);
                    facade.SendMessageCommand(NotiConst.UPDATE_START, updateFiles);
                    if (Initialize)
                    {
                        StartCoroutine(OnUpdateResourceUpdate(updateFiles));
                    }
                }
                else
                {
                    _dic.Add("reason", "remote_no_resource");
                    ThinkingAnalyticsAPI.Track("not_need_hot_update", _dic);
                    OnResourceInited();
                }

                yield return null;
            }
        }

        /// <summary>
        /// 开始下载 真正的开始下载文件
        /// </summary>
        /// <returns></returns>
        public IEnumerator OnUpdateResourceUpdate(List<string> listFiles) 
        {
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, "正在更新中");
            var random = DateTime.Now.ToString("yyyymmddhhmmss");
            string remote = AppConst.appVersion;
            float downMB = _updateItemMB;
            float totalMB = _updateItemMB;
            for (int i = 0; i < listFiles.Count; i++)
            {
                var keyValue = listFiles[i].Split('|');
                totalMB += float.Parse(keyValue[2]) / 1024;
            }

            //刷新要更新文件数量
            facade.SendMessageCommand(NotiConst.UPDATE_COUNT, listFiles.Count.ToString());

            //初始化下载进度
            string initStr = "正在更新中：" + downMB.ToString("f2") + "/" + totalMB.ToString("f2") + "MB" + "_" + downMB.ToString("f2") + "_" + totalMB.ToString("f2");
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, initStr);
			bool hasError = false;
            for (var j = 0; j < listFiles.Count; j++)
            {
                if (listFiles[j].Length <= 0)
                    continue;

                var fileItem = listFiles[j];
                var keyValue = fileItem.Split('|');
                if (keyValue[0].EndsWith(".meta") || keyValue[0].EndsWith(".txt") || keyValue[0].EndsWith(".bat"))
                    continue;

                var downloadUrl = AppConst.WebUrl + remote + "\\" + keyValue[0] + "?v=" + random;
                var downloadFile = Util.DataPath + keyValue[0];
                yield return DownLoadFile(downloadUrl, downloadFile, fileItem);
				if (hasDownloadFileError)
					hasError = true;
                downMB += float.Parse(keyValue[2]) / 1024;
                string me = "正在更新中：" + downMB.ToString("f2") + "/" + totalMB.ToString("f2") + "MB" + "_" + downMB.ToString("f2") + "_" + totalMB.ToString("f2");
                facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, me);
            }
			if (hasError)
			{
				//facade.SendMessageCommand(NotiConst.DOWNLOAD_FILE_FAILED);
				yield break;
			}
            needSilenceUpdate = false;
            string message = "更新完成，准备进入游戏";
            facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);
            yield return new WaitForEndOfFrame();

            var fsV = new FileStream(Util.DataPath + "version.txt", FileMode.OpenOrCreate);
            var swV = new StreamWriter(fsV);
            swV.WriteLine(remote);
            swV.Close();
            fsV.Close();

            var hasUpdateFilesPath = Util.DataPath + "update_files.txt";
            if (File.Exists(hasUpdateFilesPath)) 
            {
                File.Delete(hasUpdateFilesPath);
            }
            
            facade.SendMessageCommand(NotiConst.UPDATE_FINISH);

            OnResourceInited();
        }

        void CheckAudit()
        {
            var d = LitJson.JsonMapper.ToObject(AppConst.remoteConfigStr);
            string[] versions = AppConst.originVersion.Split('.');
            if (versions.Length >= 3)
            {
                int version = int.Parse(versions[0]) * 10000 + int.Parse(versions[1]) * 100 + int.Parse(versions[2]);

                if( d.Keys.Contains("AuditList") && d["AuditList"].Keys.Contains(version.ToString()))
                {
                    int v = int.Parse(d["AuditList"][version.ToString()].ToString());
                    if (v > 0 )
                    {
                        AppConst.UpdateMode = false;
                        AppConst.forceChannel = v;
                    }
                }
            }
        }
		IEnumerator CheckDrawingState()
		{
			//版本和谐资源状态切换
			var random1 = DateTime.Now.ToString("yyyymmddhhmmss");
			string drawingStateUrl = AppConst.WebUrl + "GlobalConfig.txt?v=" + random1;
            using (var request = UnityWebRequest.Get(drawingStateUrl))
			{
				yield return request.SendWebRequest();

				if (request.isHttpError || request.isNetworkError)
				{
                    Debug.Log(">>>>>>>下载出错" + drawingStateUrl);
					// 下载出错
					UnityEngine.Debug.Log(request.error + drawingStateUrl);
				}
				else
				{
                    Debug.Log(">>>>>>>下载成功" + drawingStateUrl);
                    // 下载完成
                    var data = request.downloadHandler.text;
					AppConst.remoteConfigStr = data;
                    if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
                    {
                        Debug.Log("AppConst.remoteConfigStr==");
                        Debug.unityLogger.logEnabled = AppConst.remoteConfigStr.Contains("\"DebugEnable\":1");
                    }
                    var d = LitJson.JsonMapper.ToObject(data);
                    var v = d["DrawingState"].ToString();
                    int.TryParse(v, out AppConst.drawingState);
                    // 优先释放request 会降低内存峰值
                    request.Dispose();
                }
			}
		}
        IEnumerator OnCheckSilence()
        {
            var Assets_Url = AppConst.WebUrl;    //资源服务器地址
            var random = DateTime.Now.ToString("yyyymmddhhmmss");
            var inremote = Assets_Url + "version.txt?v=" + random;
           
            using (var request = UnityWebRequest.Get(inremote))
            {
                yield return request.SendWebRequest();

                if (request.isHttpError || request.isNetworkError)
                {
                    // 下载出错
                    UnityEngine.Debug.Log(request.error + inremote);
                }
                else
                {
                    // 下载完成
                    string[] lines = request.downloadHandler.text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);//忽略空行;
                    Debug.Log("remote version==" + request.downloadHandler.text);
                    Debug.Log("AppConst.appVersion==" + request.downloadHandler.text);
                    if (lines.Length > 1 && lines[1] == "1" && lines[0] != AppConst.appVersion)
                    {
                        needSilenceUpdate = true;
                        CheckSilenceUpdate();
                    }
                }
                request.Dispose();
            }
        }
        /// <summary>
        /// 启动更新下载，这里只是个思路演示，此处可启动线程下载更新
        /// </summary>
        IEnumerator OnUpdateResource()
        {
            if (!needSilenceUpdate)
            {
                yield return CheckDrawingState();
                CheckAudit();
            }

            yield return OnUpdateResourceStart();
        }

        public IEnumerator DownLoadFile(string infile, string outfile, string item = "",int failedRepeatCount = 5)
        {

            using (var request = UnityWebRequest.Get(infile))
            {
                yield return request.SendWebRequest();

                if (request.isHttpError || request.isNetworkError)
                {
                    // 下载出错
                    UnityEngine.Debug.LogError(request.error + infile + "重试");
					
					if (failedRepeatCount > 0)
					{
						yield return DownLoadFile(infile, outfile, item, failedRepeatCount - 1);
                    }
                    else
                    {
                        //修改为.unity3d后缀的AB才阻断。
                        if (infile.Contains(".unity3d"))
                        {
                            hasDownloadFileError = true;
                            hasDownloadFileNetworkError = request.isNetworkError;
                            string message = "下载失败，请重试";
                            Debug.LogError(message + outfile + "重试多次后依旧失败");
                            facade.SendMessageCommand(NotiConst.DOWNLOAD_FILE_FAILED, message);
                            yield break;
                        }
                    }
                }
                else
                {
                    // 下载完成
                    var fileData = request.downloadHandler.data;

                    var path = Path.GetDirectoryName(outfile);
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path ?? throw new InvalidOperationException());
                    }

					using (var fs = new FileStream(outfile, FileMode.Create))
					{
						fs.Write(fileData, 0, fileData.Length);
					}
					hasDownloadFileError = false;
					hasDownloadFileNetworkError = false;
					if (!string.IsNullOrEmpty(item))
                    {
                        var hasUpdateFilesPath = Util.DataPath + "update_files.txt";
                        using (var sw = new StreamWriter(hasUpdateFilesPath, true))
                        {
							//Debug.Log("开始写入已更新完成的包==" + item);
                            sw.WriteLine(item);
                        }
                    }
                    // 优先释放request 会降低内存峰值
                    request.Dispose();
                }
            }
        }


        public void startCheckMapPrefab(LuaFunction callback = null)
        {
            if (AppConst.delayLoadModel && !_hasUpdateAllResource && _updateMapFiles.Count > 0)
                StartCoroutine(updateMapPrefab(callback));
            else
            {
                if (LuaHelper.GetPanelManager().uiDownLoad != null)
                    Destroy(LuaHelper.GetPanelManager().uiDownLoad);
                if (callback != null)
                    callback.Call();
            }
        }

        IEnumerator updateMapPrefab(LuaFunction callback)
        {
            LuaHelper.GetPanelManager().uiDownLoad.SetActive(true);
            if (_updateMapFiles.Count > 0)
            {
                //LuaHelper.GetPanelManager().ShowUI("UIDo")
                facade.SendMessageCommand(NotiConst.UPDATE_COUNT, _updateMapFiles.Count.ToString());

                for (var i = 0; i < _updateMapFiles.Count; i++)
                {
                    var message = "正在更新中：" + (i + 1) + "/" + _updateMapFiles.Count;
                    facade.SendMessageCommand(NotiConst.UPDATE_MESSAGE, message);

                    BeginDownload(_updateMapFiles[i][0], _updateMapFiles[i][1]);
                    while (!(IsDownOK(_updateMapFiles[i][1]))) { yield return new WaitForEndOfFrame(); }
                }
            }

            if (LuaHelper.GetPanelManager().uiDownLoad != null)
            {
                Destroy(LuaHelper.GetPanelManager().uiDownLoad);
            }
            _updateMapFiles.Clear();
            yield return new WaitForEndOfFrame();
            _hasUpdateAllResource = true;
            if (callback != null)
                callback.Call();
        }

        /// <summary>
        /// 是否下载完成
        /// </summary>
        bool IsDownOK(string file) {
            return _downloadFiles.Contains(file);
        }

        /// <summary>
        /// 线程下载
        /// </summary>
        void BeginDownload(string url, string file) {     //线程下载
            var param = new object[2] { url, file };

            var ev = new ThreadEvent {Key = NotiConst.UPDATE_DOWNLOAD};
            ev.evParams.AddRange(param);
            ThreadManager.AddEvent(ev, OnThreadCompleted);   //线程下载
        }

        /// <summary>
        /// 线程完成
        /// </summary>
        /// <param name="data"></param>
        void OnThreadCompleted(NotiData data) {
            switch (data.evName) {
                case NotiConst.UPDATE_EXTRACT:  //解压一个完成
                //
                break;
                case NotiConst.UPDATE_DOWNLOAD: //下载一个完成
                _downloadFiles.Add(data.evParam.ToString());
                break;
            }
        }

        /// <summary>
        /// 资源初始化结束
        /// </summary>
        public void OnResourceInited() {
            if(!Initialize)
            {
                facade.SendMessageCommand(NotiConst.UPDATE_LOGIN);
                ResManager.Initialize(AppConst.AssetDir, OnInitialize);
                //GameObject.Find("WWiseAudio").GetComponent<WwiseManager>().AddBasePath();
            }
        }

        public void ShareTexture(Action callback)
        {
            StartCoroutine(CaptureScreenshot(callback));
        }

        public static IEnumerator CaptureScreenshot(Action callback)
        {
            yield return new WaitForEndOfFrame();//在当前帧绘制完后才截屏

            //Rect rect = new Rect(0, (Screen.height - 1920) / 2, Screen.width, Screen.height);
            Rect rect = new Rect(0, 0, Screen.width, Screen.height);
            RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 24);
            Texture2D screenShot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);

            foreach (var camera in Camera.allCameras)
            {
                if (camera.isActiveAndEnabled)
                {
                    camera.targetTexture = rt;
                    camera.Render();
                    camera.targetTexture = null;
                }
            }

            RenderTexture prevActiveTex = RenderTexture.active;
            RenderTexture.active = rt;
            screenShot.ReadPixels(rect, 0, 0);
            screenShot.Apply();
            RenderTexture.active = prevActiveTex;

            byte[] bytes = screenShot.EncodeToJPG();
            string filePath = Util.DataPath + "share.jpg";
            File.WriteAllBytes(filePath, bytes);
            //callback?.invoke();
            if (callback != null)
            {
                callback.Invoke();
                Debug.Log(filePath);
            }
            Destroy(screenShot);
            Destroy(rt);
            yield return null;
        }

        void OnInitialize() {
            //ResourceManager rs = AppFacade.Instance.GetManager<ResourceManager>(ManagerName.Resource);
            //rs.LoadPrefab("FZYASHJW_Zhong", delegate (GameObject obj)
            //{
            //
            //});


            LuaManager.InitStart();
            LuaManager.DoFile("Logic/Game");         
            Util.CallMethod("Game", "OnInitOK");     //初始化完成
            Initialize = true;
        }

 
        /// <summary>
        /// 析构函数
        /// </summary>
        void OnDestroy() {
            //if (NetManager != null) {
            //    NetManager.Unload();
            //}
            if (LuaManager != null) {
                LuaManager.Close();
            }
            // PacketDispatcher.close();
            Util.Log("~GameManager was destroyed");
        }
		private void OnApplicationFocus(bool focus)
		{
			Util.CallMethod("Game", "OnApplicationFocus",focus);
		}

        public void SDK2Unity_CallbackHandle(string code)
        {
            string[] strs = code.Split('|');
            if (strs.Length == 2)
            {
                if (strs[0] == "10")
                {
                    Debug.Log("PaySuc:" + strs[1]);
                }
                else if (strs[0] == "11")
                {
                    Debug.Log("PayFail:" + strs[1]);
                }
            }
        }

        private void OnApplicationPause(bool pause)
		{
            var wm = AppFacade.Instance.GetManager<WebMsgManager>(ManagerName.WebMsg);
            if( wm != null && !wm.IsConnected())
            {
                return;
            }
            if (!pause)
            {
                if (pauseTime < 0.001f || Time.realtimeSinceStartup - pauseTime < 300)
                {
                    Util.CallMethod("ConnectManager", "ShowWaiting");
                    pauseTime = Time.realtimeSinceStartup;
                }
                else
                {
                    Util.CallMethod("ConnectManager", "ForceBreakReconnect");
                }
                Util.Log("Resume Game");
#if UNITY_EDITOR || !UNITY_IOS
                AkSoundEngineController.Instance.ActivateAudio(true);
#endif
                ThinkingAnalyticsAPI.Track("ta_app_start");
            }
            else
            {
                Util.Log("Pause Game");
                pauseTime = Time.realtimeSinceStartup;
#if UNITY_EDITOR || !UNITY_IOS
                AkSoundEngineController.Instance.ActivateAudio(false);
#endif
                ThinkingAnalyticsAPI.Track("ta_app_end");
                Util.CallMethod("Game", "OnApplicationPause");
            }
        }
	}
}